﻿#if !MONOGAME

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;

namespace Brain
{
    /// <summary>
    /// Helper for rendering instanced objects
    /// </summary>
    public class InstancingSystem
    {
        /// <summary>
        /// The Default Vertex Declaration, being 4 BlendWeight Vertex Elements, that can form
        /// a Matrix 4x4
        /// </summary>
        public static readonly VertexDeclaration InstanceVertexDeclaration = new VertexDeclaration
        (
            new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 0),
            new VertexElement(16, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 1),
            new VertexElement(32, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 2),
            new VertexElement(48, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 3)
        );

        /// <summary>
        /// The Vertex Buffer of the Model you are rendering
        /// </summary>
        public VertexBuffer ModelVertexBuffer { get; set; }
        /// <summary>
        /// The Index Buffer of the Model you are rendering
        /// </summary>
        public IndexBuffer ModelIndexBuffer { get; set; }

        

        /// <summary>
        /// A Dynamic Vertex Buffer that normally holds the Instances World Matrixes
        /// </summary>
        public DynamicVertexBuffer InstancesVertexBuffer { get; protected set; }

#if MONOGAME
        public Type Type;
#else
        /// <summary>
        /// The Vertex Declaration this instance is using
        /// </summary>
        public VertexDeclaration VertexDeclaration { get; protected set; }
#endif

        /// <summary>
        /// Makes a new instance of the InstancingHelper class
        /// </summary>
        /// <param name="ModelVertexBuffer"></param>
        /// <param name="ModelIndexBuffer"></param>
        /// <param name="VertexDeclaration"></param>
        public InstancingSystem(VertexBuffer ModelVertexBuffer,
            IndexBuffer ModelIndexBuffer,
#if !MONOGAME
            VertexDeclaration VertexDeclaration
#else
            Type type
#endif
            )
        {
            this.ModelVertexBuffer = ModelVertexBuffer;
            this.ModelIndexBuffer = ModelIndexBuffer;
            this.VertexDeclaration = VertexDeclaration;

#if MONOGAME
            this.InstancesVertexBuffer = new DynamicVertexBuffer(Engine.Instance.GraphicsDevice,
                type, ModelVertexBuffer.VertexCount, BufferUsage.WriteOnly);
            this.Type = type;
#else
            this.InstancesVertexBuffer = new DynamicVertexBuffer(Engine.Instance.GraphicsDevice,
                this.VertexDeclaration, 16, BufferUsage.WriteOnly);
#endif
        }
        /// <summary>
        /// Makes a new instance of the InstancingHelper class, using
        /// as the VertexDeclaration the default InstancingSystem.InstanceVertexDeclaration
        /// </summary>
        /// <param name="ModelVertexBuffer"></param>
        /// <param name="ModelIndexBuffer"></param>
        public InstancingSystem(VertexBuffer ModelVertexBuffer,
            IndexBuffer ModelIndexBuffer
#if MONOGAME
            ,Type type
#endif
            )
            : this(ModelVertexBuffer, ModelIndexBuffer, InstanceVertexDeclaration
#if MONOGAME
            ,type
#endif
            )
        {
        }

        /// <summary>
        /// Resizes the Buffer to a greater size if it's not big enough
        /// </summary>
        /// <param name="instances"></param>
        public virtual void ResizeBufferIfNotBig(int instances)
        {
            if (instances > InstancesVertexBuffer.VertexCount)
            {
                InstancesVertexBuffer.Dispose();

#if MONOGAME
                this.InstancesVertexBuffer = new DynamicVertexBuffer(Engine.Instance.GraphicsDevice,
                    Type, ModelVertexBuffer.VertexCount, BufferUsage.WriteOnly);
#else
            this.InstancesVertexBuffer = new DynamicVertexBuffer(Engine.Instance.GraphicsDevice,
                this.VertexDeclaration, instances, BufferUsage.WriteOnly);
#endif
            }
        }
    }
}

#endif